
Berta.SettingsRenderer = new Class(function(){
	
	return {
		
		options: null,
		defaults: {},
		
		statics: {
			_instance: null, // Singleton instance
			instance: function(options) {
				if(!Berta.SettingsRenderer._instance) {
					Berta.SettingsRenderer._instance = new Berta.SettingsRenderer(options);
				}
				
				return Berta.SettingsRenderer._instance;
			},
			
			types: [], // available types for rendering
			addType: function(name, typeRenderer) {
				if(jQuery.isArray(name)) {
					for(var i = 0; i < name.length; i++)
						this.types[name[i]] = typeRenderer;
				} else {
					this.types[name] = typeRenderer;
				}
			},
			buildEditorParams: function(params, editor_params) {
				var p = $.extend({}, params);
				delete p.title;
				delete p.name;
				delete p.description;
				delete p.type;
				
				p['editor_params'] = editor_params;
				
				return p;
			}
		},
		

		//   .______    __    __  .______    __       __    ______    ////////////////////////////////////////////////////////////
		//   |   _  \  |  |  |  | |   _  \  |  |     |  |  /      |   ////////////////////////////////////////////////////////////
		//   |  |_)  | |  |  |  | |  |_)  | |  |     |  | |  ,----'   ////////////////////////////////////////////////////////////
		//   |   ___/  |  |  |  | |   _  <  |  |     |  | |  |        ////////////////////////////////////////////////////////////
		//   |  |      |  `--'  | |  |_)  | |  `----.|  | |  `----.   ////////////////////////////////////////////////////////////
		//   | _|       \______/  |______/  |_______||__|  \______|   ////////////////////////////////////////////////////////////
	
		constructor: function(options) {
			this.options = jQuery.extend({}, this.defaults, options);
			
		},
		
		/**
		 * Return HTML rendered settings
		 * @param {Array} settingNamesList		e.g., [ '-', 's:test.testSetting' '- Group Name', 't:test.anotherSetting', '-' ]
		 */
		getRenderedFromNamesList: function(settingNamesList, context) {
			var elements = $('<div></div>'), s, d, i, sName, cName;
			for(i = 0; i < settingNamesList.length; i++) {
				if(settingNamesList[i][0] === '-') {
					// title of a section is given
					elements.append('<hr />');
					if(settingNamesList[i].length > 2)
						elements.append('<h4>' + settingNamesList[i].substr(2) + '</h4>');
				
				} else {
					// name is given
					sName = settingNamesList[i];
					cName = 'template-settings';
					sParams = '';
					if (sName.substr(1, 1) == ':') {
						switch(sName.substr(0, 1)) {
							case 's': cName = 'settings'; break;
							case 't': cName = 'template-settings'; break;
							case 'e': cName = 'entry-settings'; break;
						}
						sName = sName.substr(2);
					}

					if(cName == 'template-settings') {
						cName += '.' + Berta.Options.template_id;
					}

					if(sName.indexOf(':') != 0) {
						sParams = sName.split(':');
						sName = sParams.shift(sParams);
					}
					
					//$.log(cName, sName, sParams);
										
					d = Berta.Settings.instance().getDefinition(cName, sName);

					elements.append(this.getRenderedSetting(cName, d, false/*route_params*/, sParams));


					/*if(d && !d.renderType) d.renderType = d.type;

					console.log(d);
					
					if(d && this.statics.types[d.renderType]) {
						if (cName == 'entry-settings') {
							elements.append(self.getRenderedSetting(collection, d, route_params));
							//this.statics.types[d.renderType].call(this, cName, sName, d, sParams));
						} else {
							s = Berta.Settings.instance().getSetting(cName, sName);
							elements.append(this.statics.types[d.renderType].call(this, cName, sName, d, s));
						}
					} else if(d) {
						elements.append('<p>ERROR! "' + cName + '/' + sName + '" has no renderer!</p>');
						$.logWarn('SettingsRenderer: setting "' + cName + '/' + sName + '" has no renderer!');
					} else {
						elements.append('<p>ERROR! "' + cName + '/' + sName + '" undefined!</p>');
						$.logWarn('SettingsRenderer: setting "' + cName + '/' + sName + '" undefined!');
					}*/
				}
			}
			
			// init .x-editable instances
			Berta.EditorManager.instance().registerEditables(
				elements.find('.x-editable'), 
				context ? context : 'panel', 
				this._(onEditorChange), 
				this._(onEditorSave), 
				this._(onEditorRevert)
			);
			
			// return jQuery object
			return elements.contents();
		},
		
		
		getRenderedFromDefinitions: function(collection, definitions, context, route_params) {
			var elements = $('<div></div>'), self = this, s;
			//$.log(definitions);
			
			var currentGroupName = null, currentGroupDiv = null;
			jQuery.each(definitions, function(key, d) {
				if(d.group != currentGroupName) {
					if(currentGroupDiv !== null) {
						elements.append(currentGroupDiv);
					}

					elements.append($('<h4 class="x-pane-subheading x-pane-subheading-foldable" />').html(d.group));
					currentGroupName = d.group;
					currentGroupDiv = $('<div />');
				}
				
				currentGroupDiv.append(self.getRenderedSetting(collection, d, route_params));
			});

			// Add the last group to the pane
			if(currentGroupDiv !== null) {
				elements.append(currentGroupDiv);
			}
			
			// init .x-editable instances
			Berta.EditorManager.instance().registerEditables(
				elements.find('.x-editable'), 
				context ? context : 'panel', 
				this._(onEditorChange), 
				this._(onEditorSave), 
				this._(onEditorRevert)
			);
			
			// return jQuery object
			return elements.contents();
		},


		getRenderedSetting: function(collection, definition, route_variables, additional_params) {
			var html, s;
			if(!definition.renderType) definition.renderType = definition.type;
			if(definition.renderType && this.statics.types[definition.renderType]) {

				if(collection != 'entry-settings') {
					s = Berta.Settings.instance().getSetting(collection, definition.name);
				}

				if(null === route_variables || typeof route_variables != 'object') {
					route_variables = {};
				}

				if(collection.indexOf('.') > 0) {
					collection = collection.split('.');
					route_variables['id'] = collection[1];
					collection = collection[0];
				}

				html = this.statics.types[definition.renderType](
					{
						'setting_collection': collection,
						'setting_collection_id': route_variables.id,
						// Pass route variables in case we're dealing with tempalte-settings or section-settings
						'route_variables': route_variables,

						// !!!! additional_params are used only for gallery as array(0 => entry_id)
						'additional_params': additional_params
					}, definition, s);

			} else {
				html = '<p>ERROR! ' + collection + '/' + definition.name + ' has no renderer!</p>';
				$.logWarn('SettingsRenderer: setting ' + collection + '/' + definition.name + ' has no renderer!');
			}

			return html;
		}
	};


	
	
	//   .______   .______     __  ____    ____  ___   .___________. _______    //////////////////////////////////////////////////
	//   |   _  \  |   _  \   |  | \   \  /   / /   \  |           ||   ____|   //////////////////////////////////////////////////
	//   |  |_)  | |  |_)  |  |  |  \   \/   / /  ^  \ `---|  |----`|  |__      //////////////////////////////////////////////////
	//   |   ___/  |      /   |  |   \      / /  /_\  \    |  |     |   __|     //////////////////////////////////////////////////
	//   |  |      |  |\  \--.|  |    \    / /  _____  \   |  |     |  |____    //////////////////////////////////////////////////
	//   | _|      | _| `.___||__|     \__/ /__/     \__\  |__|     |_______|   //////////////////////////////////////////////////

	function onEditorChange(editor) {
		if(editor.options.pluginOptions.cssconn) {
			this._(cssConnection)(editor.getValue(), editor.options.pluginOptions);
		}
	}
	function onEditorRevert(editor) {
		if(editor.options.pluginOptions.cssconn) {
			this._(cssConnection)(editor.getValue(), editor.options.pluginOptions);
		}
	}
	function onEditorSave(editor) {
		if(editor.options.pluginOptions.cssconn) {
			//$.log(editor.getValue());
			this._(cssConnection)(editor.getValue(), editor.options.pluginOptions);
		}

		//$.log(editor.options, editor.getValue());

		// Update setting in Berta.Settings
		if(editor.options.setting_collection && editor.options.variable) {

			var coll = editor.options.setting_collection;
			if(editor.options.setting_collection_id) coll += '.' + editor.options.setting_collection_id;


			Berta.Settings.instance().setSetting(
				coll,	// Setting_collection is set when calling renderer
				editor.options.variable,				// Variable is the variable for the editor
				editor.getValue()
			);

			// Remove cached settings from local storage
			Berta.Settings.instance().clearLocalSettingsCache(editor.options.setting_collection_id, true);
		}
		
	}
	
	
	
	function cssConnection(value, editorPluginOptions) {
		var i, c = editorPluginOptions.cssconn, el, replEl, d;
		
		var cssValue = value;
		//if(editorPluginOptions.unit) cssValue += editorPluginOptions.unit;
		
		if (c.length > 0) {
			for (i = 0; i < c.length; i++) {
				
				// change the CSS rule to change all elements on page
				changeRule(c[i].selector, c[i].property, cssValue);
				
				// Find element(s) corresponding to the rule.
				$(c[i].selector).each(function() {
					var d = $(this).data(Berta.Editor.DATA_REPLACEMENT);
					if(d) {
						$('#' + d).css(c[i].property, cssValue);
						return false;	// we're expecting only one element in editing mode, i.e.,
										// with a replacement element
					}
				});
			}
		}
	}
	
	function changeRule(selectorText, property, value) {
		var ss = document.styleSheets, rules, i, j;
        for (i = 0; i < ss.length; i++) {
			rules = ss[i].cssRules || ss[i].rules;
			for (j = 0; j < rules.length; j++) {
				if (rules[j].selectorText === selectorText) {
					//$.log('before', property, rules[j].style.getPropertyValue(property));
					rules[j].style.setProperty(property, value, '');
					//$.log('after', property, rules[j].style.getPropertyValue(property));
					
					//rules[j].style.color = "green";
				}
			}
		}
	}
	
	
	
	
	
	
	
	
}());


